

from typing import List,Union
import sys,os
#sys.path.append("C:\\Users\\Administrator\\Desktop\\VSCode\\IMS")
    
from fastapi import APIRouter,Depends,UploadFile,File
from fastapi.responses import FileResponse
# from fastapi.logger import logger
from tortoise.transactions import atomic,in_transaction
from tortoise.expressions import Q

from models import Project,User,ProjectMembers,ProjectFiles,ProjectGroups,ProjectLog
from scheams import (Project_Pydantic,ProjectIn_Pydantic
                     ,Response200,Response400
                     ,ProjectMembers_Pydantic,ProjectInWithId_Pydantic
                     ,ProjectMembersWithId_Pydantic
                     ,ProjectFiles_Pydantic,ProjectGroups_Pydantic
                     ,User_Pydantic,ProjectQuery)
from core import deps,config,get_logger
from utils import project_utils

logger = get_logger(__name__)

project = APIRouter(tags=["项目相关"],dependencies=[Depends(deps.get_current_user)])

@project.post("/save_project",summary="保存项目")
async def save_project(project_form:ProjectIn_Pydantic
                       ,project_menbers_forms: List[ProjectMembers_Pydantic]
                       ,user:User = Depends(deps.get_current_user)):
    # 该方法体内整体为一个事务
    async with in_transaction():
        temp_project : Project = await Project.filter(project_name=project_form.project_name)
        if temp_project :
            return Response400(msg="请勿重复保存" if temp_project[0].project_owner_id==user.username else "存在同名项目，无法保存")
        
        project_form.statu = config.Settings.ProjectStatus.DRAFT
        
        project : Project = await Project.create(**project_form.dict(),project_owner=user)
        
        for item in project_menbers_forms:
            await ProjectMembers.create(**item.dict(),project=project)
    
    return Response200(msg="保存成功",data=await Project_Pydantic.from_tortoise_orm(project))

@project.post("/submit_project",summary="提交项目")
async def submit_project(project_form:ProjectInWithId_Pydantic
                       ,project_menbers_forms: List[ProjectMembersWithId_Pydantic]
                       ,user:User = Depends(deps.get_current_user)
                       ):
    # 该方法体内整体为一个事务
    async with in_transaction():
        temp_project = None
        # 若是无项目id 则为直接提交
        if not project_form.id:
            temp_project : Project = await Project.filter(project_name=project_form.project_name,statu__not=config.settings.ProjectStatus.CANCELED)
            if temp_project :
                return Response400(msg="请勿重复提交" if temp_project[0].project_owner==user.username else "存在同名项目，无法提交")
        
        total = 0
        for item in project_menbers_forms:
            total += item.menbers_percentage
        if not total.__eq__(100):
            return Response400(msg="成员贡献占比总和不为100")
        
        
        pre_statu = project_form.statu
        project_form.statu = config.Settings.ProjectStatus.SUBMITTED
        
        # 创建项目编码
        project_form.project_code = await project_utils.createPoejectCode(project_form.project_group)
        
        project = None
        if not project_form.id:
            logger.debug(project_form.model_dump())
            dict = project_form.model_dump()
            dict.pop("id")
            project = await Project.create(**dict,project_owner=user)
        else:
            dict = project_form.model_dump()
            logger.debug(dict)
            dict["project_owner_id"] = user.username
            dict.pop("id")
            logger.debug(dict)
            await Project.filter(id=project_form.id).update(**dict)
            project = await Project.get(id=project_form.id)
            
        logger.debug(project)
        await ProjectLog.create(project=project,pre_statu=pre_statu,statu=project.statu,user=user)
        
        for item in project_menbers_forms:
            if not item.id:
                dict = item.model_dump()
                dict.pop("id")
                await ProjectMembers.create(**dict,project_id=project.id)
            else:
                memberDict = item.model_dump()
                memberDict["project_id"] = project.id
                memberDict.pop("id")
                await ProjectMembers.filter(id=item.id).update(**memberDict)
                
        
    return Response200(msg="保存成功",data=await Project_Pydantic.from_tortoise_orm(project))
    
@project.post("/delete_project_member/{id}",summary="删除项目成员")
async def delete_project_member(id: int):
    await ProjectMembers.filter(id=id).delete()
    return Response200(msg="删除成功")
    
@project.post("/save_files",summary="保存项目文件")
async def save_files(project_id: int,files: List[UploadFile],user:User = Depends(deps.get_current_user)):
    
    
    for file in files:
    
        save_path = os.path.join(config.settings.FILE_PATH,user.department)

        if not os.path.exists(save_path):
            os.mkdir(save_path)
        
        file_name = "-".join([user.username,file.filename])
        
        save_file = os.path.join(save_path,file_name)
        
        data = await file.read()
        with open(save_file,'wb') as sf:
            sf.write(data)
            
        logger.debug("save file:{}".format(save_file))
        await ProjectFiles.create(project_id=project_id,file_path=file_name)
    
    return Response200(msg="上传成功")

@project.get("/getFilesList/{project_id}",summary="查询项目文件列表")
async def getFilesList(project_id: int):
    return Response200(data=await ProjectFiles_Pydantic.from_queryset(ProjectFiles.filter(project_id=project_id)))


@project.post("/delete_file/{file_id}",summary="删除文件")
async def delete_file(file_id: int,user:User = Depends(deps.get_current_user)):
    async with in_transaction():
        path = os.path.join(config.settings.FILE_PATH,user.department)
        projectFile = await ProjectFiles.get(id=file_id)
        logger.debug("删除文件：{}".format(os.path.join(path,projectFile.file_path)))
        await projectFile.delete()
        os.remove(os.path.join(path,projectFile.file_path))
    return Response200(msg="删除成功")

@project.get("/download_file/{file_id}",summary="下载文件")
async def download_file(file_id: int,user:User = Depends(deps.get_current_user)):
    path = os.path.join(config.settings.FILE_PATH,user.department)
    projectFile = await ProjectFiles.get(id=file_id)
    logger.debug("下载文件: {}".format(os.path.join(path,projectFile.file_path)))
    return FileResponse(path=os.path.join(path,projectFile.file_path),filename=projectFile.file_path)

@project.get("/project",summary="查询项目列表")
async def project_list(limit: int = 10,page: int = 1):
    skip = (page - 1)*limit
    # 分页 page：页码 limit: 每页记录数量
    return Response200(data=await Project_Pydantic.from_queryset(Project.all().offset(skip).limit(limit)))

@project.post("/getProjectsByState",summary="查询已提交项目列表")
async def getProjectsByState(limit: int = 10
                             ,page: int = 1
                             ,statu: config.settings.ProjectStatus = config.settings.ProjectStatus.DRAFT
                             ,user:User = Depends(deps.get_current_user)):
    skip = (page - 1)*limit
    # 分页 page：页码 limit: 每页记录数量
    
    baseQuery = Project.filter(statu=statu,project_owner_id=user.username)
    cnt = await baseQuery.count()
    records = await Project_Pydantic.from_queryset(baseQuery.offset(skip).limit(limit))
    
    return Response200(data={"cnt": cnt,
                             "records": records})
    

@project.post("/getProjectsByUser",summary="查询用户所有已提交项目列表（排除作废、草稿）")
async def getProjectsByUser(projectQuery: ProjectQuery
                            ,limit: int = 10
                             ,page: int = 1
                             ,user:User = Depends(deps.get_current_user)):
    skip = (page - 1)*limit
    # 分页 page：页码 limit: 每页记录数量
    
    
    baseQuery = Project.filter(statu__not_in=[config.settings.ProjectStatus.CANCELED,config.settings.ProjectStatus.DRAFT],project_owner_id=user.username)
    
    baseQuery = project_utils.projectQueryBuiler(projectQuery,baseQuery)
    
    cnt = await baseQuery.count()
    records = await Project_Pydantic.from_queryset(baseQuery.offset(skip).limit(limit))
    
    return Response200(data={"cnt": cnt,
                             "records": records})


@project.get("/getProjectMembers/{id}",summary="根据项目id查询项目成员")
async def getProjectMembers(id: int):
    return Response200(data=await ProjectMembersWithId_Pydantic.from_queryset(ProjectMembers.filter(project_id=id)))

@project.post("/cancelProject",summary="作废项目")
async def cancelProject(id: int,user:User = Depends(deps.get_current_user)):
    project = await Project.get(id=id)
    pre_statu = project.statu
    project.statu = config.settings.ProjectStatus.CANCELED
    await project.save()
    await ProjectLog.create(project=project,pre_statu=pre_statu,statu=project.statu,user=user)
    return Response200()

# @project.put("/update_project/{id}",summary="更新项目")
# async def update_project(id: int,project_form: ProjectIn_Pydantic):
#     if await Project.filter(id=id).update(**project_form.dict()):
#         return {"msg": "update success"}
#     return {"msg": "update error"}

# @project.put("/commit_project/{id}",summary="提交项目")
# async def commit_project(id: int,project_form: ProjectIn_Pydantic):
#     pass
    
# @project.delete("/delete_project/{id}",summary="删除项目")
# async def delete_project(id: int):
#     if await Project.filter(id=id).delete():
#         return {"msg": "delete success"}
#     return {"msg": "delete error"}

